part of internal;

class Screen {
   PreElement _pe;
   int _top;
   int _height;
   int _width;

   // generators
   Screen (DoublyLinkedList<Line> rend, int height, int width) {
      _pe = new PreElement();
      _pe.style
         ..boxSizing = 'border-box'
         ..margin = '0'
         ..display = 'flex'
         ..flexGrow = '1'
         ..flexShrink = '0'
         ..flexDirection = 'column'
         ..alignItems = 'flex-start'
         ..fontFamily = 'inherit'
         ..fontSize = 'inherit'
         ..position = 'relative'
         ..overflow = 'auto';
      _top = 0;
      _height = height;
      _width = width;
      List<DivElement> lde = new List<DivElement>(_height);
      for (int i = 0; i < _height; i++) lde[i] = _makeNull();
      _pe.children = lde;
      redraw(rend);
   }

   // internal
   static DivElement _makeNull () {
      SpanElement se = new SpanElement();
      se.nodes.add(new Text('~'));
      DivElement de = new DivElement();
      de.children.add(se);
      de.style
         ..flexBasis = '1em'
         ..flexShrink = '0';
      return de;
   }

   // mutators
   void redraw (DoublyLinkedList<Line> rend) {
      if (_top >= rend.len) throw new ArgumentError();
      List<DivElement> lde = new List<DivElement>(_height);
      for (int i = 0; i < _height; i++) {
         if (_top + i >= rend.len) lde[i] = _makeNull();
         else lde[i] = rend.nth(_top + i).line;
      }
      _pe.children = lde;
   }
   void makeVisible (DoublyLinkedList<Line> rend, int n) {
      if (dev) if (n >= rend.len) throw new ArgumentError();
      if (n >= _top && n < _top + _height);
      else if (n < _top) _top = n;
      else _top = n - _height + 1;
      redraw(rend);
   }
   
   // observers
   bool visible (int n) => n >= _top && n < _top + _height;
   int get width => _width;
   PreElement get pe => _pe;

   // invariants

   // printing
}
